#include "head.h"

// 菜单信息 - 登陆用
const wchar_t *title = L"普通用户菜单";
const wchar_t *option_1[] = {L"登录", L"注册", L"返回"};

// 菜单信息 - 管理员用
const wchar_t *title_root = L"用户菜单";
const wchar_t *option_root[] = {
    L"设定航班",
    L"修改航班",
    L"修改普通用户",
    L"增加超级用户",
    L"退出"};

// 菜单信息 - 普通用户用
const wchar_t *title_user = L"用户菜单";
const wchar_t *option_user[] = {
    L"购票退票",
    L"余额充值",
    L"查看航班",
    L"修改密码",
    L"我的订单",
    L"退出"};

// 系统初始化
FlightSystem Sys_init(void)
{
    FlightSystem Flight_sys;
    Flight_sys.Flight_list = D_List_init();   // 航班信息
    Flight_sys.ADMIN_USER = S_List_init();    // 管理员账户信息
    Flight_sys.REGULAR_USER = S_List_init();  // 普通用户信息
    Flight_sys.SILVER_USER = S_List_init();   // 银卡会员信息 (9折)
    Flight_sys.GOLD_USER = S_List_init();     // 金卡会员信息 (8折)
    Flight_sys.PLATINUM_USER = S_List_init(); // 白金会员信息 (7折)

    // 从文件中导入数据
    D_List_file_scanf(Flight_sys.Flight_list);                  // 航班信息
    S_List_File_scanf(Flight_sys.ADMIN_USER, ADMIN_FILE);       // 管理员账户信息文件
    S_List_File_scanf(Flight_sys.REGULAR_USER, REGULAR_FILE);   // 普通用户信息文件
    S_List_File_scanf(Flight_sys.SILVER_USER, SILVER_FILE);     // 银卡会员信息文件 (9折)
    S_List_File_scanf(Flight_sys.GOLD_USER, GOLD_FILE);         // 金卡会员信息文件 (8折)
    S_List_File_scanf(Flight_sys.PLATINUM_USER, PLATINUM_FILE); // 白金会员信息文件 (7折)

    system("clear");
    return Flight_sys;
}

// 注册"
U_data Sys_Register()
{
    system("clear");
    U_data data = {0};
    // 用户信息合表
    U_list *list = S_List_init();
    U_list *list_1 = S_List_init();
    FlightSystem Flight_sys = Sys_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)
    //
    S_List_File_scanf(list_1, REGULAR_FILE); // 普通用户信息文件
    // 开始注册
    printf("请输入用户名: ");
    char username[30];
    scanf("%s", username);
    // 判断用户名是否存在
    if (S_List_find_name(list, username) != NULL)
    {
        printf("用户名已存在\n");
        usleep(30 * 1000);
        printf("请按回车继续\n");
        getchar();
        getchar();
        return data;
    }
    // 输入密码
    printf("请输入密码: ");
    char password[30];
    scanf("%s", password);

    // 单链表的插入

    strcpy(data.name, username);
    strcpy(data.passwd, password);
    data.grade = 2;
    data.value = 0;
    S_List_insert(list_1, data, 1);
    // 写入文件
    S_List_File_print(list_1, REGULAR_FILE);
    system("clear");
    printf("注册成功\n");
    S_List_free(&list);
    S_List_free(&list_1);
    usleep(30 * 1000);
    printf("请按回车继续\n");
    getchar();
    getchar();
    return data;
}

// 系统登录
U_data Sys_log_in(FlightSystem Flight_sys)
{
    // 用户信息合表
    U_list *list = S_List_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)

    // 开始登录
    U_data log_data = Log_in(list);
    return log_data;
}

// 系统菜单
void Sys_menu(F_list *Flight_list, U_data log_data)
{
    // 用户信息合表
    int buy = 0;
    const wchar_t *title = L"购票系统";
    const wchar_t *choices[] = {L"购票", L"退票", L"退出"};
    FlightSystem Flight_sys = Sys_init();
    U_list *list = S_List_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)
    // 分支

    int flag = 0;
    while (1)
    {
        switch (log_data.grade)
        {
        case 1:
            // 管理员功能界面
            printf("欢迎管理员用户登陆\n");
            flag = display_menu(title_root, option_root, 5);
            break;
        default:
            // 普通用户功能界面
            printf("欢迎普通用户登陆\n");
            flag = display_menu(title_user, option_user, 6) + 5;
            break;
        }

        // 菜单选项分支处理
        switch (flag)
        {
        case 1:
            // 管理员 - 设定航班
            Set_Flight();
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 2:
            // 管理员 - 修改航班
            Amend_Flight();
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 3:
            // 管理员 - 修改普通用户
            Amend_Regular();
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 4:
            // 管理员 - 增加超级用户
            Add_admin();
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 5:
            return;
        case 6:
            // 用户 - 购票退票
            buy = display_menu(title, choices, 3);
            if (buy == 1)
            {
                system("clear");
                D_List_sort(Flight_list);
                D_List_print(Flight_list);
                Buy_Tickets(&log_data);
            }
            else if (buy == 2)
            {
                system("clear");
                Order_Form(log_data);
                Refund_Ticket(&log_data);
            }
            // system("clear");
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 7:
            // 用户 - 余额充值
            Top_Up(log_data);
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 8:
            // 用户 - 查看航班
            D_List_sort(Flight_list);
            D_List_print(Flight_list);
            break;
        case 9:
            // 用户 - 修改密码
            Change_Password(log_data);
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        case 10:
            // 用户 - 我的订单
            Order_Form(log_data);
            printf("请按回车继续\n");
            getchar();
            break;
        case 11:
            return;
        default:
            printf("请按回车继续\n");
            getchar();
            getchar();
            break;
        }
    }
    return;
}
// 管理员 - 设定航班
void Set_Flight()
{
    system("clear");
    F_list *Flight_list = D_List_init();
    D_List_file_scanf(Flight_list);
    // F_node *ptr =NULL;
    F_data data; // 航班信息
    //--
    system("clear");
    printf("请输入航班班次：");
    scanf("%d", &data.id);
    if (NULL != D_List_find_id(Flight_list, data.id))
    {
        printf("航班班次已存在，请重新输入。");
        return;
    }
    printf("请选择飞机机型：\n\t1. Boeing_737\n\t2. Airbus_A320\n\t3. Boeing_787\n\t4. Airbus_A330\n\t5.Airbus_A350\n");
    int choice;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
        strcpy(data.flighttype, "Boeing_737");
        break;
    case 2:
        strcpy(data.flighttype, "Airbus_A320");
        break;
    case 3:
        strcpy(data.flighttype, "Boeing_787");
        break;
    case 4:
        strcpy(data.flighttype, "Airbus_A330");
        break;
    case 5:
        strcpy(data.flighttype, "Airbus_A350");
        break;
    default:
        printf("无效的选择，请重新输入。");
        return;
    }
    printf("请输入航班起点站：");
    scanf("%s", data.startcity);
    printf("请输入航班终点站：");
    scanf("%s", data.arrivecity);
    printf("请输入起飞时间（时：分）：");
    scanf("%d:%d", &data.starttime[0], &data.starttime[1]);
    printf("请输入到达时间（时：分）：");
    scanf("%d:%d", &data.arrivetime[0], &data.arrivetime[1]);
    printf("请输入飞行时间：");
    scanf("%s", data.flytime);
    printf("请输入票价：");
    scanf("%d", &data.value);
    printf("请输入额定载客量：");
    scanf("%d", &data.maxNUM);
    data.leftbuyersa = 7;
    data.whetherfly = 'n';
    D_List_insert(Flight_list, data, 1);
    printf("\t\t添加成功\n");
    D_List_file_print(Flight_list);
    D_List_free(&Flight_list);
}

// 管理员 - 修改航班
void Amend_Flight()
{
    system("clear");
    F_list *Flight_list = D_List_init();
    int id;
    printf("请输入要修改的航班班次：");
    scanf("%d", &id);
    D_List_file_scanf(Flight_list);
    F_node *ptr = Flight_list->next;
    ptr = D_List_find_id(Flight_list, id);
    if (ptr == NULL)
    {
        printf("未找到该航班，请重新输入。");
        return;
    }
    printf("请选择要修改的内容：\n\t1. 航班班次\n\t2. 飞机机型\n\t3. 起点站\n\t4. 终点站\n\t5. 起飞时间\n\t6. 到达时间\n\t7. 飞行时间\n\t8. 票价\n\t9. 额定载客量\n\t0. 退出修改\n");
    int choice;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
        printf("请输入新的航班班次：");
        scanf("%d", &ptr->data.id);
        break;
    case 2:
        printf("请输入新的飞机机型：");
        scanf("%s", ptr->data.flighttype);
        break;
    case 3:
        printf("请输入新的起点站：");
        scanf("%s", ptr->data.startcity);
        break;
    case 4:
        printf("请输入新的终点站：");
        scanf("%s", ptr->data.arrivecity);
        break;
    case 5:
        printf("请输入新的起飞时间（时：分）：");
        scanf("%d:%d", &ptr->data.starttime[0], &ptr->data.starttime[1]);
        break;
    case 6:
        printf("请输入新的到达时间（时：分）：");
        scanf("%d:%d", &ptr->data.arrivetime[0], &ptr->data.arrivetime[1]);
        break;
    case 7:
        printf("请输入新的飞行时间：");
        scanf("%s", ptr->data.flytime);
        break;
    case 8:
        printf("请输入新的票价：");
        scanf("%d", &ptr->data.value);
        break;
    case 9:
        printf("请输入新的额定载客量：");
        scanf("%d", &ptr->data.maxNUM);
        break;
    case 0:
        break;
        ;
    default:
        printf("输入错误，请重新输入。");
        return;
    }
    printf("修改成功！\n");
    D_List_file_print(Flight_list);
    D_List_free(&Flight_list);
    // display_menu(title_root, option_root, 4);
}

// 管理员 - 修改普通用户
void Amend_Regular()
{
    system("clear");
    FlightSystem Flight_sys = Sys_init();
    U_list *list = S_List_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)
    //---------------------------
    char user[16];
    printf("请输入要修改的用户：");
    scanf("%s", user);
    U_node *ptr = S_List_find_name(list, user);
    if (ptr == NULL)
    {
        printf("未找到该用户，请重新输入。");
        return;
    }
    //-----------------------
    S_List_clear(list);
    char grade[30]; // 用户等级
    switch (ptr->data.grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        break;
    case 3:
        strcpy(grade, SILVER_FILE);
        break;
    case 4:
        strcpy(grade, GOLD_FILE);
        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        break;
    default:
        break;
    }
    S_List_File_scanf(list, grade);
    ptr = S_List_find_name(list, user);
    //-------
    printf("请选择要修改的内容：\n\t1. 用户名\n\t2. 密码\n\t3. 余额\n\t4. 退出修改\n");
    int choice;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
        printf("请输入新的用户名：");
        scanf("%s", ptr->data.name);
        break;
    case 2:
        printf("请输入新的密码：");
        scanf("%s", ptr->data.passwd);
        break;
    case 3:
        printf("请输入新的余额：");
        scanf("%d", &ptr->data.value);
        break;
    case 4:
        return;
    default:
        printf("无效的选择，请重新输入。");
        return;
    }
    S_List_File_print(list, grade);
    S_List_free(&list);
}

// 管理员 - 增加超级用户
void Add_admin()
{
    system("clear");
    FlightSystem Flight_sys = Sys_init();
    U_list *list = S_List_init();
    U_list *list_a = S_List_init();
    U_list *list_b = S_List_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)
                                                         //---------------------------找到用户
    char user[16];
    printf("请输入要修改的用户：");
    scanf("%s", user);
    U_node *ptr = S_List_find_name(list, user);
    if (ptr == NULL)
    {
        printf("未找到该用户，请重新输入。");
        return;
    }
    //-----------------------
    char grade[30]; // 用户等级
    switch (ptr->data.grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        break;
    case 3:
        strcpy(grade, SILVER_FILE);
        break;
    case 4:
        strcpy(grade, GOLD_FILE);
        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        break;
    default:
        break;
    }
    // 找到用户后，修改用户等级
    if (ptr->data.grade == 1)
    {
        printf("该用户已是超级用户，无需再增加。");
        return;
    }
    ptr->data.grade = 1;
    //----------------------插入管理员账户信息文件
    S_List_File_scanf(list_a, ADMIN_FILE);
    S_List_insert(list_a, ptr->data, 1);
    S_List_File_print(list_a, ADMIN_FILE);
    //-------删除用户
    S_List_File_scanf(list_b, grade);
    S_List_delete_name(list_b, ptr->data.name);
    S_List_File_print(list_b, grade);
    //-----------------------
    S_List_free(&list);
    S_List_free(&list_a);
    S_List_free(&list_b);
    return;
}

// 用户 - 购票
void Buy_Tickets(U_data *log_data)
{
    // system("clear");
    float discount = 1;
    U_list *list = S_List_init();
    F_list *Flight_list = D_List_init();
    S_arr_list *arr_list = S_Arr_Init();
    char grade[30];
    //--------------确认用户等级和文件
    switch ((*log_data).grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        break;
    case 3:
        strcpy(grade, SILVER_FILE);
        discount = 0.9;
        break;
    case 4:
        strcpy(grade, GOLD_FILE);
        discount = 0.8;
        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        discount = 0.7;
        break;
    default:
        break;
    }
    S_List_File_scanf(list, grade); // 读取用户信息
    //------------------------------
    int id;
    printf("请输入要购买的航班班次：");
    scanf("%d", &id);
    //------------
    D_List_file_scanf(Flight_list); // 读取航班信息
    /// 查找航班
    F_node *ptr = Flight_list->next;
    ptr = D_List_find_id(Flight_list, id);
    if (ptr == NULL)
    {
        printf("未找到该航班请重新输入。");
        return;
    }
    // 查找用户
    U_node *nod = S_List_find_name(list, (*log_data).name);
    if (nod == NULL)
    {
        printf("未找到该用户，请重新输入。");
        return;
    }
    // 判断余额
    if (nod->data.value < ptr->data.value * discount)
    {
        printf("余额不足，请充值。\n");
        return;
    }
    // 判断票额
    if (ptr->data.leftbuyersa == 0)
    {
        printf("该航班已售罄，请重新选择。\n");
        return;
    }
    // 判断是否已经购买
    S_Arr_read(arr_list);
    int pos = S_Arr_Find_id_u(arr_list, id, (*log_data).name);
    if (pos != -1)
    {
        printf("您已购买该航班，请勿重复购买。\n");
        return;
    }
    // 更新余额
    nod->data.value -= (int)((ptr->data.value) * discount);
    // 更新票额
    ptr->data.leftbuyersa--;
    // 写入订单信息
    S_Arr_insert(arr_list, 1, ptr->data, (*log_data).name);
    // 写入文件
    D_List_file_print(Flight_list);
    S_List_File_print(list, grade);
    S_Arr_save(arr_list);
    // 释放内存
    S_List_free(&list);
    D_List_free(&Flight_list);
    S_Arr_free(&arr_list);
    return;
}

// 用户 - 退票
void Refund_Ticket(U_data *log_data)
{
    // system("clear");
    float discount = 1; // 折扣
    U_list *list = S_List_init();
    F_list *Flight_list = D_List_init();
    S_arr_list *arr_list = S_Arr_Init();
    // 确定用户文件和等级
    char grade[30];
    switch ((*log_data).grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        discount = 1;
        break;
    case 3:
        strcpy(grade, SILVER_FILE);
        discount = 0.9;
        break;
    case 4:
        strcpy(grade, GOLD_FILE);
        discount = 0.8;
        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        discount = 0.7;
        break;
    default:
        break;
    }
    // 从文件读取
    S_List_File_scanf(list, grade);
    D_List_file_scanf(Flight_list);
    S_Arr_read(arr_list); // 读取订单信息
    // 查找用户
    U_node *nod = S_List_find_name(list, (*log_data).name);
    ////--------------------------------------- 查找航班
    int id; // 航班id
    printf("请输入要退票的航班班次：");
    scanf("%d", &id);
    F_node *ptr = Flight_list->next;
    ptr = D_List_find_id(Flight_list, id);
    if (ptr == NULL)
    {
        printf("航班已经起飞。");
        return;
    }
    //--------------------------------找到订单
    char user[16];                  // 用户名
    strcpy(user, (*log_data).name); // 用户名
    int pos_1 = S_Arr_Find_id_u(arr_list, id, user);
    if (pos_1 == -1)
    {
        printf("用户没有这个订单\n");
        return;
    }
    //---------------------------------修改
    S_Arr_delete(arr_list, pos_1);                          // 删除订单
    nod->data.value += (int)((ptr->data.value) * discount); // 更新余额
    ptr->data.leftbuyersa++;                                // 更新票额
    //-------------------------------------------
    // 写入文件
    D_List_file_print(Flight_list);
    S_List_File_print(list, grade);
    S_Arr_save(arr_list);
    // 释放内存
    S_List_free(&list);
    D_List_free(&Flight_list);
    S_Arr_free(&arr_list);
    return;
}

// 用户 - 余额充值
void Top_Up(U_data log_data)
{
    system("clear");
    U_list *list = S_List_init();
    char grade[30];
    switch (log_data.grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        break;
    case 3:
        strcpy(grade, SILVER_FILE);

        break;
    case 4:
        strcpy(grade, GOLD_FILE);

        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        break;
    default:
        break;
    }
    int value;
    S_List_File_scanf(list, grade);
    printf("请输入要充值的金额：");
    scanf("%d", &value);
    U_node *nod = S_List_find_name(list, log_data.name);
    nod->data.value += value;
    S_List_File_print(list, grade);
    S_List_free(&list);
    return;
}

// 用户 - 修改密码
void Change_Password(U_data log_data)
{
    system("clear");

    U_list *list = S_List_init();
    char grade[30]; // 用户等级
    switch (log_data.grade)
    {
    case 2:
        strcpy(grade, REGULAR_FILE);
        break;
    case 3:
        strcpy(grade, SILVER_FILE);
        break;
    case 4:
        strcpy(grade, GOLD_FILE);
        break;
    case 5:
        strcpy(grade, PLATINUM_FILE);
        break;
    default:
        break;
    }
    S_List_File_scanf(list, grade);
    char passwd[64];
    printf("请输入修改后的密码：");
    scanf("%s", passwd);
    U_node *nod = S_List_find_name(list, log_data.name);
    if (NULL != nod)
    {
        strcpy(nod->data.passwd, passwd);
        S_List_File_print(list, grade);
        S_List_free(&list);
    }
    return;
}

// 用户 - 我的订单
void Order_Form(U_data log_data)
{
    system("clear");
    S_arr_list *L = S_Arr_Init();
    S_Arr_read(L); // 读取订单信息
    int pos[100];  // 存储用户的订单
    S_Arr_Find_user(L, log_data.name, pos);

    if (pos[0] == -1)
    {
        printf("没有订单\n");
        return;
    }
    system("clear");

    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  载客量  剩余座位  是否飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");
    int n = 0;
    for (int i = 0; -1 != pos[i]; i++)
    {
        n = pos[i] - 1;
        printf("%-6d", L->data[n].id);
        printf("%-15s", L->data[n].flighttype);
        printf("%-10s", L->data[n].startcity);
        printf("%-10s", L->data[n].arrivecity);
        printf("%02d:%02d\t", L->data[n].starttime[0], L->data[n].starttime[1]);
        printf("%02d:%02d\t    ", L->data[n].arrivetime[0], L->data[n].arrivetime[1]);
        printf("%-10s\t", L->data[n].flytime);
        printf("%-6d", L->data[n].value);
        printf("%-8d", L->data[n].maxNUM);
        printf("%-8d  ", L->data[n].leftbuyersa);
        printf("%c\n", L->data[n].whetherfly);
        usleep(30 * 1000);
    }
    return;
}